<?php
// +----------------------------------------------------------------------
// | ZanPianCMS [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2013 http://www.zanpian.com All rights reserved.
// +----------------------------------------------------------------------
// | BBS:  <http://www.feifeicms.cc>
// +----------------------------------------------------------------------
namespace app\common\model;
use think\Model;
class Alipay extends Model{
    public function submit($user_id,$score_ext){
		config('pathinfo_depr','/');
		$total_fee = sprintf("%.2f",$score_ext);
        $data = array();
        $data['service'] = 'create_direct_pay_by_user';//使用即时到帐交易接口
        $data['payment_type'] = '1';//默认值为：1（商品购买）
        $data['quantity'] = '1';//数量
        $data['_input_charset'] = 'utf-8';
        $data['partner'] = trim($GLOBALS['config']['user']['pay']['alipay_appid']);
        $data['seller_email'] = trim($GLOBALS['config']['user']['pay']['alipay_account']);
        $data['out_trade_no'] = date("YmdHis").mt_rand(10000, 99999);
        $data['notify_url'] = url('home/notify/alipay',[],false,true);
        $data['return_url'] = url('home/notify/alipay',[],false,true);
        $data['subject'] = '积分充值（UID：'.$user_id.'）';
        $data['total_fee'] = $total_fee;
        $res = [
			    'order_uid'=>$user_id,
			    'order_sign'=>$data['out_trade_no'],
				'order_money'=>$total_fee,
				'order_info' =>$data['subject'],
				'order_type'=>'alipay',
                'order_code'=>$res['code_url']
        ];
		//写入订单
		if(model('Orders')->data($res)->save()!== false){
			$res['order_id']=model('Orders')->order_id;
			cookie('pay_alipay_uid_'.$user_id,$res,300);
		}
        //待请求参数数组
        $para = $this->buildRequestPara($data);
        $sHtml = "<form id='alipaysubmit' name='alipaysubmit' action='https://mapi.alipay.com/gateway.do?_input_charset=utf-8' method='POST'>";
        while (list ($key, $val) = each ($para)) {
            $sHtml.= "<input type='hidden' name='".$key."' value='".$val."'/>";
        }
        //submit按钮控件请不要含有name属性
        $sHtml = $sHtml."<input type='submit' value='正在提交'></form>";
        $sHtml = $sHtml."<script>document.forms['alipaysubmit'].submit();</script>";
        echo $sHtml;
        die;
    }

    public function notify(){
        $param = input();
        unset($param['pay_type']);
        $isSign = $this->getSignVeryfy($param,$param["sign"]);
		if($GLOBALS['config']['user']['pay']['pay_notify']==1){
		    file_put_contents(RUNTIME_PATH.'notify.txt', "收到来自支付宝的异步通知\r\n", FILE_APPEND);
            file_put_contents(RUNTIME_PATH.'notify.txt', '订单备注：' . $param['subject'] . "\r\n", FILE_APPEND);
            file_put_contents(RUNTIME_PATH.'notify.txt', '订单号：' . $param['out_trade_no'] . "\r\n", FILE_APPEND);
            file_put_contents(RUNTIME_PATH.'notify.txt', '订单金额：' . $param['total_fee'] . "\r\n\r\n", FILE_APPEND);	      
            file_put_contents(RUNTIME_PATH.'notify.txt', '支付状态：' . $param['trade_status'] . "\r\n\r\n", FILE_APPEND);
		}
        //验证成功
        if($isSign) {
            if ($param['trade_status'] == 'TRADE_SUCCESS') {
                if( model('Orders')->update_order($param['out_trade_no'],$param['total_fee'])!== false){
                    echo "success";
                }
                else{
                    echo "fail";
                }
            }
            else {
                echo "success";
            }
        }else{
            echo "fail";
        }
    }

    public function buildRequestPara($para_temp) {
        //除去待签名参数数组中的空值和签名参数
        $para_filter = $this->paraFilter($para_temp);

        //对待签名参数数组排序
        $para_sort = $this->argSort($para_filter);

        //生成签名结果
        $mysign = $this->buildRequestMysign($para_sort);

        //签名结果与签名方式加入请求提交参数组中
        $para_sort['sign'] = $mysign;
        $para_sort['sign_type'] = 'MD5';

        return $para_sort;
    }

    public function paraFilter($para) {
        $para_filter = array();
        while (list ($key, $val) = each ($para)) {
            if($key == "sign" || $key == "sign_type" || $val == "")continue;
            else	$para_filter[$key] = $para[$key];
        }
        return $para_filter;
    }

    public function argSort($para) {
        ksort($para);
        reset($para);
        return $para;
    }

    public function buildRequestMysign($para_sort) {
        //把数组所有元素，按照"参数=参数值"的模式用"&"字符拼接成字符串
        $prestr = $this->createLinkstring($para_sort);

        $mysign = $this->md5Sign($prestr, $GLOBALS['config']['user']['pay']['alipay_appkey']);

        return $mysign;
    }
    public function createLinkstring($para) {
        $arg  = "";
        while (list ($key, $val) = each ($para)) {
            $arg.=$key."=".$val."&";
        }
        //去掉最后一个&字符
        $arg = substr($arg,0,count($arg)-2);
        //如果存在转义字符，那么去掉转义
        if(get_magic_quotes_gpc()){$arg = stripslashes($arg);}

        return $arg;
    }

    public function md5Sign($prestr, $key) {
        $prestr = $prestr . $key;
        return md5($prestr);
    }

    public function getSignVeryfy($para_temp, $sign) {
        //除去待签名参数数组中的空值和签名参数
        $para_filter = $this->paraFilter($para_temp);

        //对待签名参数数组排序
        $para_sort = $this->argSort($para_filter);

        //把数组所有元素，按照"参数=参数值"的模式用"&"字符拼接成字符串
        $prestr = $this->createLinkstring($para_sort);

        $isSgin = false;
        $isSgin = $this->md5Verify($prestr, $sign,$GLOBALS['config']['user']['pay']['alipay_appkey']);

        return $isSgin;
    }

    public function md5Verify($prestr, $sign, $key) {
        $prestr = $prestr . $key;
        $mysgin = md5($prestr);
        if($mysgin == $sign) {
            return true;
        }
        else {
            return false;
        }
    }
}